package com.util;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class ZookeeperClient {

	private static final Logger logger = LoggerFactory.getLogger(ZookeeperClient.class);
//	private static final String CONNECTION_STRING = "192.168.1.232:2181,192.168.1.232:2182,192.168.1.232:2183";
	private static final String CONNECTION_STRING = "192.168.1.126:2181";
	
	public static final String SERVER_GROUP = "/servers";
	public static final String SERVER_PREFIX = "/server";
	public static String serverName = "";
	public static ZooKeeper client = null;
	public static String jettyWebServer = "";
	public static String serverId = StringUtil.createUUID();
	private static final String SERVER_PARENT_NODE = "/servers";
	
	@Autowired
	private  HttpServletRequest request;
	//spring init method
	public static void init() {
		try {
			client = new ZooKeeper(CONNECTION_STRING, 3000, new Watcher() {

				@Override
				public void process(WatchedEvent arg0) {//客户端监听
					logger.info(arg0.getPath()+"\t"+arg0.getState()+"\t"+arg0.getType());
					try {	
						client.getChildren("/", true);
					}catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		} catch (IOException e) {
			e.printStackTrace();
		}
		String serverHostInfo = null;
		if(StringUtils.isEmpty(jettyWebServer)){
			try {
				serverHostInfo = IPAddressKowalski.getIpAddressAndPort() +File.separator+serverName;
			}  catch (Exception e) {
				e.printStackTrace();
			}
		}else{
			serverHostInfo = jettyWebServer;
		}
		registServerInfo(serverHostInfo);
	}
	
	
	public static void registServerInfo(String serverName) {
		try {
			/**
			 *  1、PERSISTENT  持久化目录节点，存储的数据不会丢失。
        		2、PERSISTENT_SEQUENTIAL   顺序自动编号的持久化目录节点，存储的数据不会丢失，并且根据当前已近存在的节点数自动加 1，然后返回给客户端已经成功创建的目录节点名。
				3、EPHEMERAL  临时目录节点，一旦创建这个节点的客户端与服务器端口也就是session 超时，这种节点会被自动删除。
				4、EPHEMERAL_SEQUENTIAL 临时自动编号节点，一旦创建这个节点的客户端与服务器端口也就是session 超时，这种节点会被自动删除，并且根据当前已近存在的节点数自动加 1，然后返回给客户端已经成功创建的目录节点名。
			 */
			serverName += "#0";
			Stat sta = client.exists(SERVER_GROUP, false);
			if(sta == null)
				logger.info(client.create(SERVER_GROUP, serverName.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT));
			
			
			String url = client.create(SERVER_GROUP+SERVER_PREFIX+serverId, serverName.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
			logger.info("**************server registered:"+url+"\t hostname:"+serverName);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @description getServerHost
	 * @return
	 * @author TDW
	 * @date 2018年6月8日
	 * @modify_date 
	 * @modify_author
	 * @modify_desc
	 */
	public static ConcurrentHashMap<String, Integer> getServerHost() {
		ConcurrentHashMap<String,Integer> tempMap = null;
		try {
			List<String> zkNodeList = client.getChildren(SERVER_PARENT_NODE, false);
			tempMap = new ConcurrentHashMap<String,Integer>();
			//node data: host:port/serverName#sessionSize
			String serverHost = null;
			Integer sessionSize = 0;
			String zkNodeData = null;
			for(String zkNode : zkNodeList){
				zkNodeData = new String(client.getData(SERVER_PARENT_NODE+"/"+zkNode, false, null));
				serverHost = zkNodeData.split("#")[0];
				sessionSize = Integer.parseInt(zkNodeData.split("#")[1]);
				tempMap.put(serverHost, sessionSize);
			}
			logger.info("######服务端可用的server列表"+tempMap);
		} catch (Exception e) {
			logger.error("获取服务器失败",e);
		}
		return tempMap;
	}

	

}
